-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RangeTable: 範囲指定による表の定義 #132
Conversation
各項目について、Rangeを用いて出目の合計の範囲を指定する、表のクラス。
表のロール結果の新しいインターフェースに対応させる
表の定義において重複した項目が多かったため、RangeTableを使って短く書く
テーブルのリファクタリングの準備段階
表を振った結果の整形処理が通常と異なるため、独自のformatterを使う
目的:命中部位を求める際の複雑な文字列処理をなくすこと。 * 命中部位表をRangeTableで書く。 * 命中部位表の項目を構造体で書く。 * 致命的命中が発生し得るかを、文字列ではなくBooleanで表す。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RollResult
がクラスになっていて、こいつが表からの抽出作業をしている理由がわからないのですが、こうしないと面倒な記述を迫られるのでしょうか? コードを見た限りだと、RollResult
はただのstructでよく、 table
, formatter
はいらないように思えます、RangeTable#roll
内で値は決定できるのではないでしょうか?
少し変えたら |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
マージありがとうございました。続いて、ロール結果について、通常の |
@ochaochaocha3 マージしてから、
|
@ysakasin インターフェースを統一するために、すべてのテーブルクラスが また、他のテーブルでも、今回のRangeTableのような詳細版ロールが必要な場合(標準と違う形式で文字列を出力する場合など)が散見されるので、メソッド名を変えたうえで詳細版を用意したいと考えています。名前は…長いですが、 |
このPRは、表を少ない量のコードで記述できるクラス
RangeTable
を導入します。このクラスは、現在DiceBot#get_table_by_number
に実装されている、短く書かれた表から項目を取り出す処理を、クラスとして整備し直したものです。また、再整備にあたり、汎用性を高めました。背景・目的
「疎らな表」の定義方法
表のクラスである
Table
やD66GridTable
がカバーしていない表の定義方法として、DiceBot#get_table_by_number
で項目を取り出せる表の定義方法(以下では、これを「『疎らな表』方式」と呼びます)があります。この方法では、各項目をという形で記述します。そのため、重複項目を1つにまとめて記述でき、結果として表の定義が短く書けます。これは、ダイスボットのコードを読みやすくするのに便利です。
「疎らな表」方式の改善:範囲指定による表の定義
ただし、「疎らな表」方式には、出目の合計と対応する項目が分かりにくいという欠点があります。改善案として、以下のように、各項目と対応する出目の合計の範囲を指定する方法が考えられます。
以下では、この方法を「範囲指定による表の定義」と呼びます。
表の拡張
以下は「疎らな表」方式とは独立した話題です。
表に文字列以外の内容を表に格納したり、ダイスロール結果の情報を取得したりできると、表がより使いやすくなります。例えば、バトルテックのダイスボットでは、ダメージ(整数値)を表に格納して、ダイスロールによって取り出すことが行われています。表を振った際のダイスロール結果の情報を取得できれば、メタルヘッドのダイスボットで見られるような独自の結果整形処理も、表のクラスを用いて簡潔に書ける可能性があります。
目的
以上を踏まえて、このPRでは、以下の2つを目的とします。
RangeTable
に実装すること。RangeTable
のみを対象として、今後、他の表のクラスでも便利に使えそうか検討するための題材とします。RangeTable
クラスの使い方表を定義する
RangeTable.new(name, dice_roll_method, items)
name
String
dice_roll_method
String
"2D6"
などitems
Array<(Range, Object)>, Array<(Integer, Object)>
各項目は
[出目の合計の範囲, 内容]
という形で記述します。「出目の合計の範囲」には、整数のRange
または整数を指定できます。例:獣ノ森の「ランダム天気持続表」
各項目の「内容」は、通常は文字列ですが、文字列に限らずあらゆるオブジェクトを格納できます。
例:バトルテックの命中部位表
表の定義時に出目の合計の範囲に誤りがあった(カバーしていない範囲があった、重なっていた)場合は、例外が発生します。
表を振る
RangeTable#roll(bcdice)
bcdice
BCDice
呼び出しは
Table
クラスなどと同じインターフェースです。結果はRangeTable::RollResult
クラスのオブジェクトとして返ります。結果のオブジェクトには、以下の情報が格納されます。sum
Integer
values
Array<Integer>
content
Object
formatted
String
to_s
でも呼び出せる。例:バトルテックの「致命的命中表」
独自の結果整形処理を指定する
RangeTable.new
で表を定義するときにブロックを指定すると、独自の結果整形処理を指定できます。ブロックは以下の引数を受け取ります。table
RangeTable
result
RangeTable::RollResult
例:メタルヘッドの「アクシデントチャート(射撃・投擲)」
ダイスボットへの
RangeTable
の導入について3つのダイスボット(獣ノ森、バトルテック、メタルヘッド)に、今回作った
RangeTable
を導入してみました。それぞれ、以下のことに重点を置いています。